package algo_lignes_sites.data.pre_trt.pre_trt_path.simplif_topo;

import algo_lignes_sites.data.junction.A_Junction;
import algo_lignes_sites.data.junction.A_Junction.TypeJunction;
import algo_lignes_sites.data.junction.JunctionREF;
import algo_lignes_sites.data.path.A_Path;
import algo_lignes_sites.data.path.PathREF;
import commons.logs.Logger;
import java.util.ArrayList;


public class Pattern_PetitPath {


	static boolean traite() {

		Logger.log_DEBUG1("##### BOUCLE PATTERN PetitPath #####");


		boolean bAtLeatOneRealisation = false;

		boolean bReBoucle = true;
		while (bReBoucle) {
			bReBoucle = false;
			Logger.log_DEBUG1("~~~~ sous-boucle PATTERN PetitPath ~~~~");


			int nbP = SimplifTopo.vPathREF.size();
			for (int i=0; i<nbP; i++) {
				PathREF path = SimplifTopo.vPathREF.get(i);

				if (etudiePattern_pourCePath(path)) {

					bReBoucle = true;
					bAtLeatOneRealisation = true;

					// On continue le parcours mais la taille du vecteur de path a change ...
					nbP = SimplifTopo.vPathREF.size();
				}
			}
		}
		return bAtLeatOneRealisation;
	}


	private static boolean etudiePattern_pourCePath(PathREF path) {
		// Critère très simple
		// 1) lg path doit etre < seuil
		if (path.getLength() > (path.epaisseurTrait_reel_m+path.epaisseurDissymetrie_reel_m)*SimplifTopo.params.factor_SimplifTopo)
			return false;
		//2) une des extrémité du path doit être un Connect_2
		if (!path.from().isConnect2() && !path.to().isConnect2())
			return false;

		Logger.log_DEBUG1(" => OK pour " + path.getInfoBulle());
		SimplifTopo.nbPatternRealise_PetitPath ++;

		// On prend le path de l'autre coté du CONNECT_2 du path : path_toGrow
		// Pour faire simple, on met ce CONNECT_2 en from()
		if (!path.from().isConnect2())
			path.reverse();
		assert path.from().isConnect2();

		A_Junction jConnect2 = path.from();

		A_Path path_toGrow;
		if (jConnect2.getPathContenantNum(0) != path)
			path_toGrow = jConnect2.getPathContenantNum(0);
		else
			path_toGrow = jConnect2.getPathContenantNum(1);
		assert(path_toGrow != path);
		// On met aussi path_toGrow dans le bon sens
		if (path_toGrow.to() != jConnect2)
			path_toGrow.reverse();


		realisePattern (path, path_toGrow);
		return true;
	}


	private static void realisePattern(A_Path path, A_Path path_toGrow) {

		// Puis on parcourt les junction de path et on les donne à path_toGrow
		ArrayList<A_Junction> vJ = path.getVJunction();
		for (int i=0; i<vJ.size() ; i++) {
			A_Junction j = vJ.get(i);

			// Cas special de la 1ere junction qui doit passer de CONNECT_2 à STD
			if (i==0)
				j.setTypeJunction(TypeJunction.STD);

			j.removePathContenant(path);
			path_toGrow.addJunction(j);
			j.addPathContenant(path_toGrow);
		}

		// Cas special ou le petit path est déclaré comme connecté directement ou non à un node
		// il faut s'assurer que path_to_Grow est au moins connecté au memes node, puisque son chemin
		// comprend au moins celui du petit path
		// Un souci pourrait apparaitre dans le cas ou la zone d'influence d'un node est tres petite (pour faire sortir des piquage)
		//  et que seul un petit path connecté reellement directement au node soit déclaré comme connecté
		//  le path suivant, apres le connect_2 est trop loin pour etre déclaré connecté au node
		//  Apres disparition du petit path, il est normal que le suivant soit déclaré connecté
		path_toGrow.recupereNodeConnectedFrom(path);

		// Suppression du path
		SimplifTopo.vPathREF.remove((PathREF)path);

		// attention, si le path fait partie des path modified car deja impliqué dans un precedent pattern realise
		// il faut l'enlever, car sinon, on va le donner à manger au simplificateur de path et notamment
		// il sera sous-decoupé, et on va alors créer des junctions appartenant a un path supprime ! (va suivre alors une serie de bug tres genants)
		SimplifTopo.vPathREF_modified.remove((PathREF)path);

		// On indique le path_toGrow comme modifié
		SimplifTopo.vPathREF_modified.add((PathREF)path_toGrow);
		
		// Correction bug 13/11/2012 : si le path à suprimer avait pour autre extrémité un connect3,
		//  lui meme connecté à Path to grow (cas d'une boucle), alors à la fin, le connect3 doit etre
		//  transformé en connect2 !
		// Pour faire simple, on recalcule le type des 2 extrémité de path to grow
		path_toGrow.from().majTypeJunction();
		path_toGrow.to().majTypeJunction();

		// pas de SPI à mettre à jour
	}
}
